#include <tulip/SystemDefinition.h> 
#include <tulip/PluginLister.h>
#include <tulip/PluginLibraryLoader.h>
#include <tulip/PluginLoaderTxt.h>
#include <tulip/TlpTools.h>

#include <tulip/Graph.h>
#include <tulip/StringCollection.h>
#include <tulip/LayoutProperty.h>
//#include <tulip/SizeProperty.h>
//#include <tulip/BooleanProperty.h>
//#include <tulip/DoubleProperty.h>
//#include <tulip/IntegerProperty.h>

#include <string>
#include <iostream>
using namespace std;
using namespace tlp;

int main(int argc,char **argv) 
{
	//程序的当前工作路径
	string appDir = ".";
	//初始化Tulip的当前工作路径
	//First we initialize Tulip with basic plugins to ensure dependencies consistency
	tlp::initTulipLib(appDir.c_str());
	//设置插件的加载路径
	tlp::TulipPluginsPath = appDir;
	//tlp::PluginLibraryLoader::loadPlugins();
	//tlp::PluginLister::checkLoadedPluginsDependencies(0);

	//插件加载反应器(类似观察者模式)
	PluginLoaderTxt collector;

	//加载插件
	PluginLibraryLoader::loadPluginLibrary("ogdfsugiyama.dll", &collector);
	PluginLibraryLoader::loadPluginLibrary("DotImport.dll", &collector);
	
	//参数集合(记录插件所要用到的各种参数)
	DataSet ds;

	//导入dot文件，创建一个图
	//内部是通过调用DotImport.dll插件来实现的
	string fn = "D:\\test\\GitProject\\vns\\build\\bin\\Debug\\mrp1.dot";
	ds.set("file::filename", fn);
	Graph* graph = tlp::importGraph("graphviz", ds);
	//Graph* graph = tlp::newGraph();

	//输入参数：设置sugiyama算法所需要的参数
	StringCollection Ranking("LongestPathRanking;OptimalRanking;CoffmanGrahamRanking");
	StringCollection Crossing("BarycenterHeuristic;MedianHeuristic;SplitHeuristic;SiftingHeuristic;GreedyInsertHeuristic;GreedySwitchHeuristic");
	StringCollection HLayout("FastHierarchyLayout;FastSimpleHierarchyLayout");
	Ranking.setCurrent(0);
	Crossing.setCurrent(0);
	HLayout.setCurrent(0);
	ds.set("fails", 4);
	ds.set("runs", 15);
	ds.set("node distance", 3.0);
	ds.set("layer distance", 3.0);
	ds.set("fixed layer distance", true);
	ds.set("transpose", true);
	ds.set("arrangeCCS", true);
	ds.set("minDistCC", 20.0);
	ds.set("pageRatio", 1.0);
	ds.set("alignBaseClasses", false);
	ds.set("alignSiblings", false);
	ds.set("Ranking", Ranking);
	ds.set("Two-layer crossing minimization", Crossing);
	ds.set("Layout", HLayout);

	//输出参数：布局参数(节点和分支的参数)
	LayoutProperty layout(graph);
	string errorMsg;

	//调用sugiyama布局算法计算节点和分支的参数
	bool result = graph->applyPropertyAlgorithm("Sugiyama (OGDF)", &layout, errorMsg, NULL, &ds);

	//输出节点和分支的几何参数
	tlp::node n;
	forEach(n, graph->getNodes()) {
		tlp::Coord nodeCoord = layout.getNodeValue(n);
		cout<<"v"<<n.id <<" x="<<nodeCoord.getX() <<", y="<<nodeCoord.getY()<<endl;
	}
	tlp::edge e;
	forEach(e, graph->getEdges()) {
		std::vector<tlp::Coord> bends = layout.getEdgeValue(e);
		cout<<"e"<<e.id<<"("<<graph->ends(e).first<<","<<graph->ends(e).second<<")";
		for(int i=0;i<bends.size();i++)
		{
			cout<<"  ("<<bends[i].getX()<<", "<<bends[i].getY()<<")";
		}
		cout<<endl;
	}

	
	delete graph;
}
